#region Namespaces

using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

#endregion

namespace Vibstudio.X4NET.IO
{
    public static class Serializer
    {
        /// <summary>
        /// The serialize.
        /// </summary>
        /// <param name="value">
        /// The value.
        /// </param>
        /// <param name="xmlWriterSettings">
        /// The xml writer settings.
        /// </param>
        /// <typeparam name="T">
        /// The object of the type T.
        /// </typeparam>
        /// <returns>
        /// The value in <see cref="string"/> that correspond the xml.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// The value cannot be null.
        /// </exception>
        public static string SerializeObject<T>(T value, XmlWriterSettings xmlWriterSettings = null) where T : new()
        {
            try
            {
                var serializer = new XmlSerializer(typeof(T));

                var settings = xmlWriterSettings ?? new XmlWriterSettings
                                                    {
                                                        Encoding = new UnicodeEncoding(false, false),
                                                        Indent = false,
                                                        OmitXmlDeclaration = false
                                                    };

                using (var textWriter = new StringWriter())
                {
                    using (var xmlWriter = XmlWriter.Create(textWriter, settings))
                    {
                        serializer.Serialize(xmlWriter, value);
                    }

                    return textWriter.ToString();
                }
            }
            catch (Exception exception)
            {
                Trace.WriteLine(string.Format("Exception: {0}", exception), "Eng.IO.Serializer.SerializeObject");
                return string.Empty;
            }
        }
        
        /// <summary>
        /// The deserialize.
        /// </summary>
        /// <param name="xml">
        /// The xml.
        /// </param>
        /// <param name="xmlReaderSettings">
        /// The xml Reader Settings.
        /// </param>
        /// <typeparam name="T">
        /// The object of the type T.
        /// </typeparam>
        /// <returns>
        /// The object of the type <see cref="T"/>.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// The xml value cannot be null.
        /// </exception>
        public static T DeserializeObject<T>(string xml, XmlReaderSettings xmlReaderSettings = null)
        {
            if (string.IsNullOrEmpty(xml))
            {
                throw new ArgumentException("xml");
            }

            var serializer = new XmlSerializer(typeof(T));

            var settings = xmlReaderSettings ?? new XmlReaderSettings();

            // No settings need modifying here
            using (var textReader = new StringReader(xml))
            {
                using (var xmlReader = XmlReader.Create(textReader, settings))
                {
                    return (T)serializer.Deserialize(xmlReader);
                }
            }
        }
    }
}
